﻿// <copyright file="Camera.cs" company="Axelerate Solutions S.A.">
// Copyright (c) Axelerate Solutions S.A.  All rights reserved.
// </copyright>

namespace Axelerate.Silverlight3D.Media.Media3D
{
    using System;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Axelerate.Silverlight3D.Controls;
    
    /// <summary>
    /// File name: Camera.cs
    /// Company: Axelerate Solutions S.A.
    /// Created By: Daniel Rojas
    /// Created Date: 10/10/2008 12:00:00 h.
    /// Description: Represents an imaginary viewing position and direction in 3-D coordinate space that describes how a 3-D model is projected onto a 2-D visual.
    ///   <Modifications>
    ///   </Modifications>
    /// </summary>
    public abstract class Camera : Freezable, IFormattable
    {
        #region Fields

        /// <summary>
        /// Transform dependecy property
        /// </summary>
        public static readonly DependencyProperty TransformProperty =
                    DependencyProperty.Register(
                          "Transform",
                          typeof(Transform3D),
                          typeof(Camera),
                          new PropertyMetadata(OnTransformPropertyChanged));

        /// <summary>
        /// Internal pointer to parent viewport, necesary to calculate the aspect ratio
        /// </summary>
        internal Viewport3D parentViewport = null;
        #endregion

        #region Properties

        /// <summary>
        /// Indicates if this model needs to be re-rendered
        /// </summary>
        internal bool IsDirty
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the color allowed to emit from the Material. This is a dependency property.
        /// </summary>
        public Transform3D Transform
        {
            get
            {

                return (Transform3D)this.GetValue(TransformProperty);
            }
            set
            {
                this.SetValue(TransformProperty, value);
                value.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(TransFormValue_PropertyChanged);
            }
        }

        /// <summary>
        /// Notify if the some property of the Transform was changed
        /// </summary>
        /// <param name="sender">Object that send the event</param>
        /// <param name="e">event arguments</param>
        void TransFormValue_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            this.IsDirty = true;
        }

        /// <summary>
        /// Matrix that allow transform to the 2D screen
        /// </summary>
        internal abstract Matrix3D WorldToScreenMatrix
        {
            get;
        }

        /// <summary>
        /// Gets the screen to view space transform
        /// </summary>
        internal abstract Matrix3D ScreenToViewMatrix
        {
            get;
        }

        /// <summary>
        /// Gets the view to world transform of the camera
        /// </summary>
        internal abstract Matrix3D ViewToWorldMatrix
        {
            get;
        }
        #endregion

        protected Camera()
        {
            this.Transform = new MatrixTransform3D();
        }

        #region Methods
       
        /// <summary>
        /// Raise the Transform changed event
        /// </summary>
        /// <param name="d">DependencyObject owner of the property</param>
        /// <param name="e">DependencyPropertyChangedEventArgs with the necesary information</param>
        private static void OnTransformPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((Camera)d).NotifyPropertyChanged("Transform");
            ((Camera)d).IsDirty = true;
        }

        #endregion

        #region IFormattable Members

        public string ToString(string format, IFormatProvider formatProvider)
        {
            return this.ToString();
        }

        #endregion
    }
}
